package com.mililoan.persist.system.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import com.mililoan.common.bean.PageResultSet;
import com.mililoan.common.dao.AbstractBaseDao;
import com.mililoan.common.dao.JdbcPageResultSetDao;
import com.mililoan.common.utils.StackTraceUtil;
import com.mililoan.model.system.OpLog;
import com.mililoan.persist.system.OpLogDao;

/**
 * 系统操作日志DAO接口
 * @author taochen
 * @version 1.0
 * @since 2017-08-26
 */
@Repository("opLogDao")
public class OpLogDaoImpl extends AbstractBaseDao<OpLog> implements OpLogDao {
	private static final Logger LOGGER = LoggerFactory.getLogger(OpLogDaoImpl.class);
	private static final String SELECT_SQL = "SELECT T.ID,T.USER_ID,T.DEP_CODE,T.USER_NAME,T.OP_TIME,T.OP_TYPE,T.OPERATION,T.STATUS,T.IPADD FROM sys_op_log T";
	
	public Long add(final OpLog opLog) throws Exception{
		JdbcTemplate template = this.getJdbcTemplate();
		Long newId = new Long(0);
		final String sql = "INSERT INTO sys_op_log(USER_ID,DEP_CODE,USER_NAME,OP_TIME,OP_TYPE,OPERATION,STATUS,IPADD" 					
			+ ") VALUES (?,?,?,?,?,?,?,?)";
		
		try {
			//返回主键
			KeyHolder keyHolder = new GeneratedKeyHolder();
			template.update(new  PreparedStatementCreator(){
				public PreparedStatement createPreparedStatement(Connection con) throws SQLException {					
					PreparedStatement ps = con.prepareStatement(sql, 
								PreparedStatement.RETURN_GENERATED_KEYS);
							ps.setLong(1, opLog.getUserId());
							ps.setLong(2, opLog.getDepCode());
							ps.setString(3, opLog.getUserName());
							ps.setString(4, opLog.getOpTime());
							ps.setLong(5, opLog.getOpType());
							ps.setString(6, opLog.getOperation());
							ps.setString(7, opLog.getStatus());
							ps.setString(8, opLog.getIpadd());
					return ps;
				}
			},keyHolder);
			//获取主键
			newId = keyHolder.getKey().longValue();
		} catch (Exception e) {			
			LOGGER.error(e.getMessage());
			throw new Exception(e);
		}
		return newId;	
	}
	
	public Long update(final OpLog opLog) throws Exception {
		JdbcTemplate template = this.getJdbcTemplate();
		String sql = "UPDATE sys_op_log T SET T.USER_ID=?,T.DEP_CODE=?,T.USER_NAME=?,T.OP_TIME=?,T.OP_TYPE=?,T.OPERATION=?,T.STATUS=?,T.IPADD=?"
				+ " WHERE T.ID=?";
		try {
			template.update(sql, new PreparedStatementSetter() {			
				public void setValues(PreparedStatement ps) throws SQLException {
						ps.setLong(1, opLog.getUserId());
						ps.setLong(2, opLog.getDepCode());
						ps.setString(3, opLog.getUserName());
						ps.setString(4, opLog.getOpTime());
						ps.setLong(5, opLog.getOpType());
						ps.setString(6, opLog.getOperation());
						ps.setString(7, opLog.getStatus());
						ps.setString(8, opLog.getIpadd());
						ps.setLong(9, opLog.getId());
				}
			});
		}
		catch (DataAccessException e) {
			LOGGER.error(e.getMessage());
			throw new Exception(e);		
		}
		return opLog.getId();
	}
	
	public Long delete(Long keyId) throws Exception {
		JdbcTemplate template = this.getJdbcTemplate();
		try {
			String sql = "DELETE FROM sys_op_log WHERE ID=?";
			//String sql = "UPDATE sys_op_log T SET T.FLAG='0' WHERE T.ID=?";
			template.update(sql, new Object[] { keyId });
		} catch (DataAccessException e) {
			LOGGER.error(e.getMessage());
			throw new Exception(e);
		}
		return keyId;
	}
	
	public PageResultSet<OpLog> queryOpLogList(OpLog opLog, int page, int pageSize) throws Exception {
		JdbcTemplate template = this.getJdbcTemplate();
		ArrayList<Object> rag = new ArrayList<Object>();
		StringBuffer sql = new StringBuffer(SELECT_SQL + " WHERE 1=1");				
		if(!StringUtils.isEmpty(opLog.getUserName())){
			sql.append(" AND T.USER_NAME = ?");
			rag.add(opLog.getUserName());
		}
		if(!StringUtils.isEmpty(opLog.getOpTime())){
			sql.append(" AND T.OP_TIME = ?");
			rag.add(opLog.getOpTime());
		}
		if(!StringUtils.isEmpty(opLog.getOperation())){
			sql.append(" AND T.OPERATION = ?");
			rag.add(opLog.getOperation());
		}
		if(!StringUtils.isEmpty(opLog.getStatus())){
			sql.append(" AND T.STATUS = ?");
			rag.add(opLog.getStatus());
		}
		if(!StringUtils.isEmpty(opLog.getIpadd())){
			sql.append(" AND T.IPADD = ?");
			rag.add(opLog.getIpadd());
		}
		final JdbcPageResultSetDao<OpLog> pageDao = new JdbcPageResultSetDao<OpLog>(pageSize);
		pageDao.setPage(page);
		final List<OpLog> pagelist = pageDao.getPrs().getResult();
		PageResultSet<OpLog> l_pageResultSet = null;
		try {
			l_pageResultSet = pageDao.pageResultSet(sql.toString(), template, rag.toArray(), new RowCallbackHandler() {	
				public void processRow(ResultSet rs) throws SQLException {
					pagelist.add(buildOpLog(rs));
				}			
			});
		} catch (Exception e) {			
			LOGGER.error(e.getMessage());
			throw new Exception(e);
		}
		return l_pageResultSet;
	}
	
	@SuppressWarnings({"unchecked", "rawtypes"})
	public OpLog getOpLogById(Long keyId) throws Exception {
		JdbcTemplate template = this.getJdbcTemplate();
		OpLog opLog = new OpLog();
		String sql = new String(SELECT_SQL + " WHERE T.ID = ?");
		
		try {
			opLog = (OpLog)template.queryForObject(sql, new Object[] { keyId },
					new RowMapper() {
						public Object mapRow(ResultSet rs, int rowNum) throws SQLException {						
						return buildOpLog(rs);
					}
				}
			);
		} catch (Exception e) {
			LOGGER.error(e.getMessage());
			throw new Exception(e);
		}
		return opLog;
	}
	
	private OpLog buildOpLog(ResultSet rs) {
	 	OpLog rsOpLog = new OpLog();
	 	try {
			rsOpLog.setId(rs.getLong("ID"));
			rsOpLog.setUserId(rs.getLong("USER_ID"));
			rsOpLog.setDepCode(rs.getLong("DEP_CODE"));
			rsOpLog.setUserName(rs.getString("USER_NAME"));
			rsOpLog.setOpTime(rs.getString("OP_TIME"));
			rsOpLog.setOpType(rs.getLong("OP_TYPE"));
			rsOpLog.setOperation(rs.getString("OPERATION"));
			rsOpLog.setStatus(rs.getString("STATUS"));
			rsOpLog.setIpadd(rs.getString("IPADD"));
		} catch (Exception e) {
            LOGGER.error(StackTraceUtil.getStackTrace(e));
        }
		return rsOpLog;
	 }
}